# 1
import akshare as ak
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime, timedelta

# 设置中文字体显示
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

# 获取平安银行近2年数据
print("正在获取股票数据...")
stock_data = ak.stock_zh_a_hist(symbol="000001", 
                               period="daily", 
                               start_date="20220101", 
                               end_date="20241201")

# 数据预处理
stock_data['日期'] = pd.to_datetime(stock_data['日期'])
stock_data = stock_data.sort_values('日期').reset_index(drop=True)

print(f"获取到 {len(stock_data)} 条数据")
print("数据样例：")
print(stock_data[['日期', '开盘', '收盘', '成交量']].head())

# 2
# 🎯 核心策略：双均线交叉（就这5行！）
stock_data['MA5'] = stock_data['收盘'].rolling(5).mean()
stock_data['MA20'] = stock_data['收盘'].rolling(20).mean()
stock_data['signal'] = 0
stock_data.loc[stock_data['MA5'] > stock_data['MA20'], 'signal'] = 1  # 买入信号
stock_data.loc[stock_data['MA5'] < stock_data['MA20'], 'signal'] = -1  # 卖出信号

print("策略核心逻辑：")
print("✅ 当5日均线 > 20日均线时：买入（做多）")
print("❌ 当5日均线 < 20日均线时：卖出（做空）")
print("⏸️  当5日均线 = 20日均线时：观望")

# 3
# 计算收益率
stock_data['daily_return'] = stock_data['收盘'].pct_change()

# 策略收益（第二天按今天的信号执行）
stock_data['strategy_return'] = stock_data['signal'].shift(1) * stock_data['daily_return']

# 计算累计收益
stock_data['cumulative_strategy'] = (1 + stock_data['strategy_return'].fillna(0)).cumprod()
stock_data['cumulative_benchmark'] = (1 + stock_data['daily_return'].fillna(0)).cumprod()

# 去掉空值
stock_data = stock_data.dropna()

print(f"回测期间：{stock_data['日期'].min().strftime('%Y-%m-%d')} 至 {stock_data['日期'].max().strftime('%Y-%m-%d')}")
print(f"交易天数：{len(stock_data)} 天")

# 4
# 创建图表
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(14, 12))

# 子图1：股价与均线
ax1.plot(stock_data['日期'], stock_data['收盘'], label='收盘价', alpha=0.8, linewidth=1)
ax1.plot(stock_data['日期'], stock_data['MA5'], label='5日均线', color='orange', linewidth=2)
ax1.plot(stock_data['日期'], stock_data['MA20'], label='20日均线', color='red', linewidth=2)

# 标记买卖点
buy_signals = stock_data[(stock_data['signal'] == 1) & (stock_data['signal'].shift(1) != 1)]
sell_signals = stock_data[(stock_data['signal'] == -1) & (stock_data['signal'].shift(1) != -1)]

ax1.scatter(buy_signals['日期'], buy_signals['收盘'], color='red', marker='^', s=60, label='买入信号', zorder=5)
ax1.scatter(sell_signals['日期'], sell_signals['收盘'], color='green', marker='v', s=60, label='卖出信号', zorder=5)

ax1.set_title('平安银行(000001) - 股价与双均线策略', fontsize=14, fontweight='bold')
ax1.legend()
ax1.grid(True, alpha=0.3)

# 子图2：收益率对比
ax2.plot(stock_data['日期'], (stock_data['cumulative_strategy'] - 1) * 100, 
         label='双均线策略', color='red', linewidth=2)
ax2.plot(stock_data['日期'], (stock_data['cumulative_benchmark'] - 1) * 100, 
         label='买入持有', color='blue', linewidth=2)

ax2.set_title('累计收益率对比 (%)', fontsize=14, fontweight='bold')
ax2.legend()
ax2.grid(True, alpha=0.3)
ax2.set_ylabel('收益率 (%)')

# 子图3：信号分布
signal_counts = stock_data['signal'].value_counts().sort_index()
colors = ['green', 'gray', 'red']
labels = ['卖出信号', '观望', '买入信号']
bars = ax3.bar([-1, 0, 1], [signal_counts.get(-1, 0), signal_counts.get(0, 0), signal_counts.get(1, 0)], 
               color=colors, alpha=0.7)

ax3.set_title('交易信号分布', fontsize=14, fontweight='bold')
ax3.set_xlabel('信号类型')
ax3.set_ylabel('天数')
ax3.set_xticks([-1, 0, 1])
ax3.set_xticklabels(labels)

# 在柱子上添加数值
for i, bar in enumerate(bars):
    height = bar.get_height()
    ax3.text(bar.get_x() + bar.get_width()/2., height + 5,
             f'{int(height)}天', ha='center', va='bottom', fontweight='bold')

plt.tight_layout()
plt.show()

# 计算关键指标
total_strategy_return = stock_data['cumulative_strategy'].iloc[-1] - 1
total_benchmark_return = stock_data['cumulative_benchmark'].iloc[-1] - 1
excess_return = total_strategy_return - total_benchmark_return

# 计算最大回撤
def calculate_max_drawdown(cumulative_returns):
    peak = cumulative_returns.expanding().max()
    drawdown = (cumulative_returns - peak) / peak
    return drawdown.min()

strategy_max_dd = calculate_max_drawdown(stock_data['cumulative_strategy'])
benchmark_max_dd = calculate_max_drawdown(stock_data['cumulative_benchmark'])

# 计算胜率
win_trades = (stock_data['strategy_return'] > 0).sum()
total_trades = (stock_data['strategy_return'] != 0).sum()
win_rate = win_trades / total_trades if total_trades > 0 else 0

# 计算年化收益和波动率
trading_days = len(stock_data)
years = trading_days / 252

strategy_annual_return = (1 + total_strategy_return) ** (1/years) - 1
benchmark_annual_return = (1 + total_benchmark_return) ** (1/years) - 1

strategy_volatility = stock_data['strategy_return'].std() * np.sqrt(252)
benchmark_volatility = stock_data['daily_return'].std() * np.sqrt(252)

# 计算夏普比率（假设无风险利率为3%）
risk_free_rate = 0.03
strategy_sharpe = (strategy_annual_return - risk_free_rate) / strategy_volatility
benchmark_sharpe = (benchmark_annual_return - risk_free_rate) / benchmark_volatility

print("=" * 60)
print("📊 策略表现报告")
print("=" * 60)
print(f"📅 回测期间: {stock_data['日期'].min().strftime('%Y-%m-%d')} 至 {stock_data['日期'].max().strftime('%Y-%m-%d')}")
print(f"📈 交易天数: {trading_days} 天 ({years:.1f} 年)")
print()
print("💰 收益表现:")
print(f"   双均线策略总收益:  {total_strategy_return:>8.2%}")
print(f"   买入持有总收益:    {total_benchmark_return:>8.2%}")
print(f"   超额收益:          {excess_return:>8.2%}")
print()
print("📊 年化指标:")
print(f"   策略年化收益:      {strategy_annual_return:>8.2%}")
print(f"   基准年化收益:      {benchmark_annual_return:>8.2%}")
print(f"   策略年化波动:      {strategy_volatility:>8.2%}")
print(f"   基准年化波动:      {benchmark_volatility:>8.2%}")
print()
print("🎯 风险指标:")
print(f"   策略最大回撤:      {strategy_max_dd:>8.2%}")
print(f"   基准最大回撤:      {benchmark_max_dd:>8.2%}")
print(f"   策略夏普比率:      {strategy_sharpe:>8.2f}")
print(f"   基准夏普比率:      {benchmark_sharpe:>8.2f}")
print()
print("🎮 交易统计:")
print(f"   交易胜率:          {win_rate:>8.2%}")
print(f"   买入信号天数:      {(stock_data['signal'] == 1).sum():>8d} 天")
print(f"   卖出信号天数:      {(stock_data['signal'] == -1).sum():>8d} 天")
print(f"   观望天数:          {(stock_data['signal'] == 0).sum():>8d} 天")

# 结果判断
print()
print("🔍 策略评价:")
if excess_return > 0:
    print(f"✅ 策略跑赢基准 {excess_return:.2%}，表现优秀！")
else:
    print(f"❌ 策略跑输基准 {abs(excess_return):.2%}，需要优化。")

if strategy_sharpe > benchmark_sharpe:
    print(f"✅ 策略夏普比率更高，风险调整后收益更好。")
else:
    print(f"❌ 策略夏普比率较低，风险调整后收益不佳。")

if abs(strategy_max_dd) < abs(benchmark_max_dd):
    print(f"✅ 策略最大回撤更小，风险控制更好。")
else:
    print(f"❌ 策略最大回撤更大，风险控制需要改进。")